<?php

require_once('Conf/file_defs.inc');

class FileController{
	var $formobj;
	var $folders_to_save = array();

	function __construct($formobj) {



		$this->formobj = $formobj;

		// exit from method if is not a file action
		if($this->formobj->inputData['is_file_action'] != 'true')
			return;


		// exec command
		switch($this->formobj->inputData['file_command']){
			case 'upload':
				$this->print_iframe(  $this->tmp_upload() );
				break;
			case 'tmp_delete':
				$this->print_json( $this->tmp_delete() );
				break;
			case 'download':
				$file_to_download = FILE_UPLOAD_PATH_TMP.
									$this->formobj->inputData['file_tmp_key'].'/'.
									$this->formobj->inputData['file_upload_id'].'/'.
									$this->formobj->inputData['file_name'];


				self::download_file($file_to_download);
				break;

		}
		exit;

	}


	function tmp_upload() {

		$tmp_key = $this->formobj->inputData['file_tmp_key'];
		if(self::authTmpId( $tmp_key )){
			// move file to tmp dir

			foreach($_FILES as $file){
				$destino_foldername = $this->formobj->inputData['file_upload_id'];

				$name =	str_replace('"','',$file["name"]);
				$name2 = str_replace('\'','',$name);
				$destino = $name2;
				
				if(!is_dir(FILE_UPLOAD_PATH_TMP.$tmp_key.'/'.$destino_foldername))
					mkdir(FILE_UPLOAD_PATH_TMP.$tmp_key.'/'.$destino_foldername);

				move_uploaded_file( $file["tmp_name"], FILE_UPLOAD_PATH_TMP.$tmp_key.'/'.$destino_foldername.'/'.$destino  );

				break;
			}

			return array(
				"file_upload_id" => $this->formobj->inputData['file_upload_id'],
				"file_name" => $destino,


				);
		}
		else
			return array();
	}

	function tmp_delete() {

		$tmp_key = $this->formobj->inputData['file_tmp_key'];

		if(self::authTmpId( $tmp_key )){
			$destino_foldername = $this->formobj->inputData['file_upload_id'];
			$destino = $this->formobj->inputData["file_name"];

			if(unlink(FILE_UPLOAD_PATH_TMP.$tmp_key.'/'.$destino_foldername.'/'.$destino )){
				return array('borrado'=>'true');
			}
			else
				return array();
		}
	}


	static function authTmpId($tmpkey) {
		return array_key_exists('tmpfolder_'.$tmpkey, $_SESSION);
	}


	function print_json($arrayData) {
		header('Content-type: application/json');
		die( json_encode($arrayData) );

	}

	function print_iframe($arrayData) {
		?>
			<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
			<html>
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
			</head>
			<body>

				
					<script type="text/javascript" src="/Media/VendorScript/jQuery/jQuery.js"></script>
					<script>
						jQuery(document).ready(function() {

							$(".fileuploadline" ,parent.document).each(function(i,e){
								if( '<?php echo $arrayData["file_name"];?>' == e.getAttribute('file_name') && '<?php echo $arrayData["file_upload_id"];?>' == e.getAttribute('file_upload_id')  ){

									$(this).find(".loading").hide();
									$(this).find(".tools").show();
								}


							});
						});
					</script>
			</body>
			</html>


		<?php
		exit;
	}


	//
	// 		VALIDATION
	//
	function final_validation($file_field) {

		global $UPLOAD_FILE_PROFILES; 
		

		if(! self::authTmpId($this->formobj->inputData['fileupload_tmpkey'])) exit;

		$tmp_dir = $this->formobj->inputData['fileupload_tmpkey'];

		// add folders to folder list to save
		$this->folders_to_save[$file_field->name] = $file_field->name;
		$tipos = explode(',', $UPLOAD_FILE_PROFILES[ $file_field->options['profile'] ]['allow_types']);
		$max_files = $file_field->options['max'];
		$max_file_size=$UPLOAD_FILE_PROFILES[ $file_field->options['profile'] ]['max_size'];


		$field_folder = FILE_UPLOAD_PATH_TMP.'/'. $tmp_dir .'/'.$file_field->name;

		// if not exist folder
		if(!is_dir($field_folder)){
			if($file_field->options['required'] == 'true')
				return array('error' => 'notfound');
			else
				return true;
		}

		// list files
		$filename_list = self::listFolder($field_folder);


		// validate max number of files
		if( count($filename_list) > $max_files )
			return array('error' => 'so_much_files');
		else
		if( count($filename_list) == 0 && $file_field->options['required'] == 'true')
			return array('error' => 'notfound');
		else
		if( count($filename_list) == 0 )
			return true;


		// validate file extensions
		$ext_errors = array();
		foreach( $filename_list as $filename ){
			// validate profile types

			$file_ext = pathinfo($filename, PATHINFO_EXTENSION);

			if(!in_array($file_ext, $tipos) && !in_array('*', $tipos)){
				
				$ext_errors['error'] = 'notvalidextension';
				$ext_errors['files'][] = $filename;

			}
		}
		if($ext_errors != array())
			return $ext_errors;


		// oversize validations
		$size_errors = array();
		foreach( $filename_list as $filename ){
			// validate profile types

			$file_size = filesize($field_folder.'/'.$filename);

			if( $max_file_size < $file_size ){
				$size_errors['error'] = 'oversize';
				$size_errors['max_size'] = round($max_file_size/1024, 2);
				$size_errors['files'][] = $filename;
			}
		}
		if($size_errors != array())
			return $size_errors;

	}

	function save($directorio) {

		$tmp_dir_name = $this->formobj->inputData['fileupload_tmpkey'];

		$from_folder = FILE_UPLOAD_PATH_TMP.$tmp_dir_name;
		$to_folder = FILE_UPLOAD_PATH.$directorio;

		foreach($this->folders_to_save as $folder_to_use) {
			self::remove_folder($to_folder.'/'.$folder_to_use);
			self::move_folder($from_folder.'/'.$folder_to_use , $to_folder.'/'.$folder_to_use);
		}

		// delete upload session
		self::remove_folder($tmp_dir_name);
		unset($_SESSION[ 'tmpfolder_'.$tmp_dir_name ]);

	}




	static function get_upload_session($dest_dir = false){

		// delete old tmp folders
		self::deleteOldTmpFolders();

		// search a new random name for tmp dir
		do {
			$tmp_dir_name = session_id().'_'.substr(str_shuffle('45sdf65asdf465wqerq6rtsdf4hgqertadfglkjqwersdfasdqwwer23467as9opzxhjfkdfassernmdfer'),0,20);
		} while(is_dir( FILE_UPLOAD_PATH_TMP . $tmp_dir_name )); 

		// create folder, set into session variable 
		@mkdir( FILE_UPLOAD_PATH_TMP . $tmp_dir_name );
		// put data dest_dir files into tmp folder

		$_SESSION['tmpfolder_'.$tmp_dir_name] = $tmp_dir_name;

		return array(
			'tmp_session' => $tmp_dir_name,
			'dest_dir' => $dest_dir
		);
	}



	// get file input html
	static function get_fileinput($file_session, $id, $multiple=true) {
		// if is multiple
		$multi = ($multiple)? ' multi="true" ' : '';

		// copy dest folder to temporal folder
		self::copy_folder(FILE_UPLOAD_PATH.$file_session['dest_dir'].'/'.$id, FILE_UPLOAD_PATH_TMP.$file_session['tmp_session'].'/'.$id);

		// uploaded row
		$rows= '';
		if (self::listFolder(FILE_UPLOAD_PATH.$file_session['dest_dir'].'/'.$id)){
			foreach( self::listFolder(FILE_UPLOAD_PATH.$file_session['dest_dir'].'/'.$id) as $f){
				$rows .= "
								<div class='fileuploadline' temp='".$file_session['tmp_session']."' file_upload_id='".$id."' file_name='".$f."'>
									<div class='tools' style=''>
										<div class='delete' onclick=\"QuickForm2.deletefile(QuickForm2.getformname(this), '". $f ."', '".$id."', '".$file_session['tmp_session']."');\" style='cursor:pointer;'></div>
										<div class='download' onclick='QuickForm2.downloadfile(this);' style='cursor:pointer;'></div>
									</div>
									<div class='uploadtitle'>".$f."</div>
								</div>
						";
			}
		}

		// input to load more files
		if( ($rows == '') || ($multi != '' && $rows != '') ) {
			$visible_input="";
		}
		else {
			$visible_input = "display:none";
		}	

			$input = '<input style="display:none;" type="file" name="'.$id.'" id="'.$id.'" ' . $multi . ' tmpkey="'.$file_session['tmp_session'].'">
						<div style="'.$visible_input.'" class="addfile" onclick="QuickForm2.addbutton(this)">'.T_('Añadir archivo').'</div>';

		return '<div class="uploaddiv">
					'. $rows .'
					'. $input .'
				</div>';
	}




	//
	//  basic folders actions
	//

	static function remove_folder($folder){

		$folder_ls = self::listFolder($folder);

		if( !is_dir($folder) || !$folder_ls ){
			@rmdir($folder);
			return false;
		}


		foreach( $folder_ls as $f ){
			$ful_f = $folder.'/'.$f;
			if(is_dir($ful_f)) {
				self::remove_folder($ful_f);
			}
			else {
				unlink($ful_f);
			}
		}
		@rmdir($folder);

		return true;
	}

	// move a folder from origin to destination
	static function move_folder($origin, $destination){
		
		if( !is_dir($origin) )
			return false;

		// if is copied remove origin
		self::copy_folder($origin, $destination);
		self::remove_folder($origin);
	}

	// copy folder from origin to destination
	static function copy_folder($src, $dst){
		if( !is_dir($src) )
			return false;

		// create full destination path
		self::createFulPath($dst);

		if (self::listFolder($src)){
			foreach(self::listFolder($src) as $f) {
				$src_full_f = $src.'/'.$f;
				$dst_full_f = $dst.'/'.$f;

				if(is_dir($src_full_f)) {
					self::copy_folder($src_full_f, $dst_full_f);
				}
				else {
					copy($src_full_f, $dst_full_f);
				}
			}
		}
	}



	// remove temporal files that is out of session
	static function deleteOldTmpFolders(){

		$tmp_upload_filelist = self::listFolder(FILE_UPLOAD_PATH_TMP);

		if(array() == $tmp_upload_filelist)
			return false;

		foreach( $tmp_upload_filelist as $f) {

			$f_fullpath = FILE_UPLOAD_PATH_TMP.$f;

			if (filemtime($f_fullpath) < time() - FILE_MAX_FILES_IN_TMP_FOLDER) {
				self::remove_folder($f_fullpath);
			}
		}

		return true;	
	}

	static function listFolder($folder){
		if( !is_dir($folder) )
			return array();

		foreach( array_diff(scandir($folder), array('.', '..')) as $f) {
			$file_list[] = $f; 
		}

		return $file_list;
	}

	static function createFulPath($path) {
		$to_create = "";
		$slash = "";
		foreach(explode('/', $path) as $fadd) {
			$to_create .= $slash.$fadd;
			if(!is_dir($to_create)) {
				mkdir($to_create);
			}

			$slash = "/";
		}
	}

	static function download_file($file_path){
		header('Content-Type: application/download');
		header('Content-Disposition: attachment; filename="'.end(explode('/',$file_path)).'"');
		header("Content-Length: " . filesize($file_path));

		$fp = fopen($file_path, "r");
		fpassthru($fp);
		fclose($fp);

	}
}